﻿// --- START OF FILE ImportCommandAdapter.cs ---

using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Analysis;
using Autodesk.Revit.UI;
using RevitProject.Helper; // RevitContextHelper
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows; // MessageBox for errors within adapter

namespace RevitProject.SpaceManager.Core 
{
    /// <summary>
    /// 导入结果的数据传输对象。
    /// </summary>
    public class ImportResult
    {
        public int CreatedCount { get; set; } = 0;
        public int SkippedCount { get; set; } = 0;
        public int ErrorCount { get; set; } = 0;
        public StringBuilder Log { get; } = new StringBuilder();
        public bool Success => ErrorCount == 0; // 或者根据你的成功定义
    }

    /// <summary>
    /// 用于导入空间类型逻辑的适配器类。
    /// </summary>
    public static class ImportCommandAdapter
    {
        /// <summary>
        /// 从指定的 CSV 文件导入空间类型。
        /// </summary>
        /// <param name="doc">Revit 文档。</param>
        /// <param name="uiApp">Revit UI 应用程序 (用于显示 TaskDialog)。</param>
        /// <param name="csvFilePath">CSV 文件的完整路径。</param>
        /// <returns>包含导入结果信息的 ImportResult 对象。</returns>
        public static ImportResult ImportFromCsv(Document doc, UIApplication uiApp, string csvFilePath)
        {
            ImportResult result = new ImportResult();

            // --- 1. 读取和解析 CSV 数据 ---
            List<SpaceTypeDataImport> typesToImport = new List<SpaceTypeDataImport>(); // 使用内部 DTO
            string[] lines;
            try
            {
                // 使用之前的编码检测方法
                Encoding detectedEncoding;
                lines = ReadCsvWithEncodingDetection(csvFilePath, out detectedEncoding);
                result.Log.AppendLine($"使用编码 {detectedEncoding?.EncodingName ?? "未知"} 读取文件。");
            }
            catch (Exception ex)
            {
                result.Log.AppendLine($"读取文件失败: {ex.Message}");
                result.ErrorCount++; // 标记为错误
                // 考虑是否在此处显示 MessageBox，或者让调用者处理
                // MessageBox.Show($"读取文件失败: {ex.Message}", "导入错误", MessageBoxButton.OK, MessageBoxImage.Error);
                return result; // 无法继续
            }

            if (lines.Length < 2)
            {
                result.Log.AppendLine("CSV 文件为空或只有表头。");
                // 不算错误，但也没有成功创建
                return result;
            }

            string headerLine = lines[0];
            if (headerLine.Length > 0 && headerLine[0] == '\uFEFF') headerLine = headerLine.Substring(1); // 移除 BOM
            string[] headers = headerLine.Split(',').Select(h => h.Trim()).ToArray();
            Dictionary<string, int> headerIndexMap = GetHeaderIndexMap(headers);

            if (!headerIndexMap.ContainsKey("名称") && !headerIndexMap.ContainsKey("Name"))
            {
                result.Log.AppendLine("CSV 文件缺少必需的表头列: '名称' (或 'Name')。");
                result.ErrorCount++;
                return result;
            }
            // 确定实际使用的名称键
            string nameKey = headerIndexMap.ContainsKey("名称") ? "名称" : "Name";

            StringBuilder parseErrors = new StringBuilder();
            for (int i = 1; i < lines.Length; i++)
            {
                string line = lines[i];
                if (string.IsNullOrWhiteSpace(line)) continue;
                string[] values = line.Split(','); // 保持简单分割

                if (values.Length <= headerIndexMap[nameKey]) { parseErrors.AppendLine($"第 {i + 1} 行数据列数不足，已跳过。"); continue; }

                SpaceTypeDataImport data = new SpaceTypeDataImport();
                try
                { /* ... 解析 CSV 行到 data 对象 ... */
                    data.Name = GetCsvValue(values, headerIndexMap, nameKey); // 使用确定的键
                    if (string.IsNullOrWhiteSpace(data.Name)) { parseErrors.AppendLine($"第 {i + 1} 行缺少名称，已跳过。"); continue; }
                    // 解析其他列 (假设 CSV 使用中文表头)
                    data.IsPlenum = ParseCsvBool(GetCsvValue(values, headerIndexMap, "是否为静压箱"), false);
                    data.AreaPerPerson_m2_person = ParseCsvDouble(GetCsvValue(values, headerIndexMap, "人均面积(m²/人)"));
                    data.LightingLoadDensity_W_m2 = ParseCsvDouble(GetCsvValue(values, headerIndexMap, "照明负荷密度(W/m²)"));
                    data.PowerLoadDensity_W_m2 = ParseCsvDouble(GetCsvValue(values, headerIndexMap, "设备负荷密度(W/m²)"));
                    data.SensibleHeatGainPerPerson_W = ParseCsvDouble(GetCsvValue(values, headerIndexMap, "人员显热(W/人)"));
                    data.LatentHeatGainPerPerson_W = ParseCsvDouble(GetCsvValue(values, headerIndexMap, "人员潜热(W/人)"));
                    data.HeatingSetpoint_C = ParseCsvDouble(GetCsvValue(values, headerIndexMap, "供暖设定点(°C)"));
                    data.CoolingSetpoint_C = ParseCsvDouble(GetCsvValue(values, headerIndexMap, "制冷设定点(°C)"));
                    data.HumidificationSetpoint_Percent = ParseCsvDouble(GetCsvValue(values, headerIndexMap, "加湿设定点(%)"));
                    data.DehumidificationSetpoint_Percent = ParseCsvDouble(GetCsvValue(values, headerIndexMap, "除湿设定点(%)"));
                    data.InfiltrationAirflowPerArea_Lps_m2 = ParseCsvDouble(GetCsvValue(values, headerIndexMap, "渗透风量(L/(s·m²))"));
                    data.OccupancyScheduleName = GetCsvValue(values, headerIndexMap, "占用率明细表");
                    data.LightingScheduleName = GetCsvValue(values, headerIndexMap, "照明明细表");
                    data.PowerScheduleName = GetCsvValue(values, headerIndexMap, "电力负荷明细表");
                    data.OutsideAirPerPerson_m3h = ParseCsvDouble(GetCsvValue(values, headerIndexMap, "每人新风量(m³/h)"));
                    data.OutsideAirPerArea_Lps_m2 = ParseCsvDouble(GetCsvValue(values, headerIndexMap, "每面积新风量(L/(s·m²))"));
                    data.AirChangesPerHour = ParseCsvDouble(GetCsvValue(values, headerIndexMap, "换气次数(/h)"));
                    data.OutdoorAirFlowStandardString = GetCsvValue(values, headerIndexMap, "新风方法");
                    typesToImport.Add(data);
                }
                catch (Exception ex) { parseErrors.AppendLine($"解析第 {i + 1} 行 ({data.Name ?? "未知"}) 出错: {ex.Message}"); }
            }

            if (parseErrors.Length > 0)
            {
                result.Log.AppendLine("--- 解析警告 ---");
                result.Log.Append(parseErrors);
               
            }

            if (typesToImport.Count == 0)
            {
                result.Log.AppendLine("未能从 CSV 文件中解析出任何有效的空间类型数据。");
                // 不一定是错误，可能文件就是空的
                return result;
            }

            // --- 2. 批量创建和设置 (事务处理) ---
            using (Transaction tx = new Transaction(doc, "批量导入空间类型"))
            {
                try
                {
                    tx.Start();
                    foreach (var data in typesToImport)
                    {
                        bool isNameUnique = !new FilteredElementCollector(doc)
                                                .OfClass(typeof(HVACLoadSpaceType))
                                                .Cast<HVACLoadSpaceType>()
                                                .Any(st => st.Name.Equals(data.Name, StringComparison.OrdinalIgnoreCase));

                        if (isNameUnique)
                        {
                            HVACLoadSpaceType newType = null;
                            try
                            {
                                newType = HVACLoadSpaceType.Create(doc, data.Name);
                                // 设置属性 (与 ViewModel 中 ExecuteImportSpaceTypesIntegrated 的逻辑相同)
                                if (data.AreaPerPerson_m2_person.HasValue && data.AreaPerPerson_m2_person > 0) newType.AreaPerPerson = UnitUtils.ConvertToInternalUnits(data.AreaPerPerson_m2_person.Value, UnitTypeId.SquareMeters);
                                if (data.LightingLoadDensity_W_m2.HasValue) newType.LightingLoadDensity = UnitUtils.ConvertToInternalUnits(data.LightingLoadDensity_W_m2.Value, UnitTypeId.WattsPerSquareMeter);
                                if (data.PowerLoadDensity_W_m2.HasValue) newType.PowerLoadDensity = UnitUtils.ConvertToInternalUnits(data.PowerLoadDensity_W_m2.Value, UnitTypeId.WattsPerSquareMeter);
                                if (data.SensibleHeatGainPerPerson_W.HasValue) newType.SensibleHeatGainPerPerson = UnitUtils.ConvertToInternalUnits(data.SensibleHeatGainPerPerson_W.Value, UnitTypeId.Watts);
                                if (data.LatentHeatGainPerPerson_W.HasValue) newType.LatentHeatGainPerPerson = UnitUtils.ConvertToInternalUnits(data.LatentHeatGainPerPerson_W.Value, UnitTypeId.Watts);
                                if (data.HeatingSetpoint_C.HasValue) newType.HeatingSetPoint = UnitUtils.ConvertToInternalUnits(data.HeatingSetpoint_C.Value, UnitTypeId.Celsius);
                                if (data.CoolingSetpoint_C.HasValue) newType.CoolingSetPoint = UnitUtils.ConvertToInternalUnits(data.CoolingSetpoint_C.Value, UnitTypeId.Celsius);
                                if (data.HumidificationSetpoint_Percent.HasValue) newType.HumidificationSetPoint = data.HumidificationSetpoint_Percent.Value / 100.0;
                                if (data.DehumidificationSetpoint_Percent.HasValue) newType.DehumidificationSetPoint = data.DehumidificationSetpoint_Percent.Value / 100.0;
                                if (data.OutsideAirPerPerson_m3h.HasValue) newType.OutdoorAirPerPerson = UnitUtils.ConvertToInternalUnits(data.OutsideAirPerPerson_m3h.Value, UnitTypeId.CubicMetersPerHour);
                                if (data.OutsideAirPerArea_Lps_m2.HasValue) newType.OutdoorAirPerArea = UnitUtils.ConvertToInternalUnits(data.OutsideAirPerArea_Lps_m2.Value, UnitTypeId.LitersPerSecondSquareMeter);
                                if (data.AirChangesPerHour.HasValue) newType.AirChangesPerHour = data.AirChangesPerHour.Value;
                                SetOutdoorAirStandard(newType, data.OutdoorAirFlowStandardString); // 使用辅助方法
                                // 设置参数
                                Parameter infiltrationParam = newType.get_Parameter(BuiltInParameter.SPACE_INFILTRATION_PARAM);
                                if (infiltrationParam != null && !infiltrationParam.IsReadOnly && data.InfiltrationAirflowPerArea_Lps_m2.HasValue) { /* ... set infiltration ... */ infiltrationParam.Set(UnitUtils.ConvertToInternalUnits(data.InfiltrationAirflowPerArea_Lps_m2.Value, UnitTypeId.LitersPerSecondSquareMeter)); }
                                SetScheduleParameterByName(newType, BuiltInParameter.SPACE_OCCUPANCY_SCHEDULE_PARAM, data.OccupancyScheduleName);
                                SetScheduleParameterByName(newType, BuiltInParameter.SPACE_LIGHTING_SCHEDULE_PARAM, data.LightingScheduleName);
                                SetScheduleParameterByName(newType, BuiltInParameter.SPACE_POWER_SCHEDULE_PARAM, data.PowerScheduleName);

                                result.CreatedCount++;
                                result.Log.AppendLine($"成功: 创建并设置了 '{data.Name}'");
                            }
                            catch (Exception ex) { result.ErrorCount++; result.Log.AppendLine($"错误: 创建/设置 '{data.Name}' 失败: {ex.Message}"); }
                        }
                        else { result.SkippedCount++; result.Log.AppendLine($"跳过: 名称 '{data.Name}' 已存在"); }
                    }
                    tx.Commit();
                }
                catch (Exception ex)
                {
                    if (tx.HasStarted() && tx.GetStatus() == TransactionStatus.Started) tx.RollBack();
                    result.Log.AppendLine($"严重错误，事务已回滚: {ex.Message}");
                    result.ErrorCount = typesToImport.Count - result.CreatedCount - result.SkippedCount; // 更新错误数
                    // 不在此处显示 MessageBox，由 ViewModel 处理
                }
            } // end using Transaction

            return result;
        }


        // --- CSV 解析和数据设置的辅助方法 (保持 private static) ---
        private static string[] ReadCsvWithEncodingDetection(string filePath, out Encoding detectedEncoding)
        { /* ... 实现 ... */
            try { string[] lines = File.ReadAllLines(filePath, Encoding.UTF8); if (lines.Length > 0 && lines[0].Contains("名称")) { detectedEncoding = Encoding.UTF8; return lines; } } catch { }
            try { string[] lines = File.ReadAllLines(filePath, Encoding.Default); if (lines.Length > 0 && lines[0].Contains("名称")) { detectedEncoding = Encoding.Default; return lines; } } catch { }
            try { Encoding utf8NoBom = new UTF8Encoding(false); string[] lines = File.ReadAllLines(filePath, utf8NoBom); if (lines.Length > 0 && lines[0].Contains("名称")) { detectedEncoding = utf8NoBom; return lines; } } catch { }
            detectedEncoding = null; throw new Exception("无法使用常见的编码格式 (UTF-8, System Default) 正确读取文件内容。");
        }
        private static Dictionary<string, int> GetHeaderIndexMap(string[] headers)
        { /* ... 实现 ... */
            Dictionary<string, int> map = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase); for (int i = 0; i < headers.Length; i++) { string header = headers[i].Trim(); if (header.StartsWith("\"") && header.EndsWith("\"") && header.Length >= 2) { header = header.Substring(1, header.Length - 2).Replace("\"\"", "\""); } if (!string.IsNullOrEmpty(header) && !map.ContainsKey(header)) map.Add(header, i); }
            return map;
        }
        private static string GetCsvValue(string[] values, Dictionary<string, int> headerIndexMap, string headerName, string defaultValue = "")
        { /* ... 实现 ... */
            if (headerIndexMap.TryGetValue(headerName, out int index)) { if (index < values.Length && !string.IsNullOrWhiteSpace(values[index])) { string val = values[index].Trim(); if (val.StartsWith("\"") && val.EndsWith("\"") && val.Length >= 2) { val = val.Substring(1, val.Length - 2).Replace("\"\"", "\""); } return val; } }
            return defaultValue;
        }
        private static double? ParseCsvDouble(string value)
        { /* ... 实现 ... */
            if (string.IsNullOrWhiteSpace(value)) return null; value = value.Replace("%", "").Trim(); if (double.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out double result)) return result; return null;
        }
        private static bool ParseCsvBool(string value, bool defaultValue)
        { /* ... 实现 ... */
            if (string.IsNullOrWhiteSpace(value)) return defaultValue; value = value.Trim().ToUpperInvariant(); if (value == "TRUE" || value == "YES" || value == "1" || value == "是") return true; if (value == "FALSE" || value == "NO" || value == "0" || value == "否") return false; return defaultValue;
        }
        private static void SetScheduleParameterByName(HVACLoadSpaceType type, BuiltInParameter bip, string scheduleName)
        { /* ... 实现 ... */
            if (!string.IsNullOrWhiteSpace(scheduleName)) { ElementId scheduleId = FindScheduleIdByName(type.Document, scheduleName); if (scheduleId != ElementId.InvalidElementId) { Parameter param = type.get_Parameter(bip); if (param != null && !param.IsReadOnly) param.Set(scheduleId); else Debug.WriteLine($"适配器警告: 无法设置只读或不存在的参数 {bip} for type '{type.Name}'"); } else Debug.WriteLine($"适配器警告: 未找到明细表 '{scheduleName}' for type '{type.Name}'"); }
        }
        private static void SetOutdoorAirStandard(HVACLoadSpaceType type, string standardString)
        { /* ... 实现 ... */
            if (!string.IsNullOrWhiteSpace(standardString))
            {
                OutdoorAirFlowStandard standardValue; if (Enum.TryParse<OutdoorAirFlowStandard>(standardString, true, out standardValue)) type.OutdoorAirFlowStandard = standardValue;
                else
                { /* ... 中文映射 ... */
                    switch (standardString)
                    {
                        case "按人数和面积":
                            standardValue = OutdoorAirFlowStandard.ByPeopleAndByArea;
                            break;
                        case "按换气次数":
                            standardValue = OutdoorAirFlowStandard.ByACH;
                            break;
                        case "最大值 (按人数, 按面积)":
                            standardValue = OutdoorAirFlowStandard.MaxByACH_ByPeopleByArea;
                            break;
                        case "最大值 (按换气次数, 按人数和面积)":
                            standardValue = OutdoorAirFlowStandard.MaxByACH_ByArea_ByPeople;
                            break;
                        case "最大值 (按换气次数, 按面积, 按人数)":
                            standardValue = OutdoorAirFlowStandard.MaxByACH_ByArea_ByPeople;
                            break;
                        default:
                            Debug.WriteLine($"导入警告: 无法识别或映射新风方法字符串 '{standardString}'。");
                            break; // 保持 resolvedStandard 为 null
                    }
                }
            }
        }
        private static ElementId FindScheduleIdByName(Document doc, string name)
        { /* ... 实现 ... */
            if (string.IsNullOrWhiteSpace(name) || name.Equals("无", StringComparison.OrdinalIgnoreCase)) return ElementId.InvalidElementId; return new FilteredElementCollector(doc).OfClass(typeof(ViewSchedule)).WhereElementIsNotElementType().FirstOrDefault(s => s.Name.Equals(name, StringComparison.OrdinalIgnoreCase))?.Id ?? ElementId.InvalidElementId;
        }

        // 内部 DTO 类定义
        private class SpaceTypeDataImport
        {
            public string Name { get; set; }
            public bool IsPlenum { get; set; }
            public double? AreaPerPerson_m2_person { get; set; }
            public double? LightingLoadDensity_W_m2 { get; set; }
            public double? PowerLoadDensity_W_m2 { get; set; }
            public double? SensibleHeatGainPerPerson_W { get; set; }
            public double? LatentHeatGainPerPerson_W { get; set; }
            public double? HeatingSetpoint_C { get; set; }
            public double? CoolingSetpoint_C { get; set; }
            public double? HumidificationSetpoint_Percent { get; set; }
            public double? DehumidificationSetpoint_Percent { get; set; }
            public double? InfiltrationAirflowPerArea_Lps_m2 { get; set; }
            public string OccupancyScheduleName { get; set; }
            public string LightingScheduleName { get; set; }
            public string PowerScheduleName { get; set; }
            public double? OutsideAirPerPerson_m3h { get; set; }
            public double? OutsideAirPerArea_Lps_m2 { get; set; }
            public double? AirChangesPerHour { get; set; }
            public string OutdoorAirFlowStandardString { get; set; }
        }
    }
}
// --- END OF FILE ImportCommandAdapter.cs ---